﻿using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;

namespace MessageTypeDescriber.Xml.Members
{
    [Serializable]
    public class MethodDescription : MemberDescription, IEquatable<MethodDescription>
    {

        public List<TypeDescription> Parameters;

        protected MethodDescription() : base(null)
        {
        }

        public MethodDescription(MethodInfo methodInfo) : base(methodInfo)
        {
            Name = methodInfo.Name;

            Parameters = new List<TypeDescription>();

            foreach (var parameter in methodInfo.GetParameters())
            {
                Parameters.Add(new TypeDescription(parameter.ParameterType));
            }

           var a = new TypeDescription(methodInfo.ReturnType);
            ReturnType = a;
        }

        public override string MemberType
        {
            get { return "Method"; }
        }

        public override string Signature
        {
            get
            {
                StringBuilder sb = new StringBuilder();

                sb.Append(ReturnType!=null?ReturnType.Signature: "");
                sb.Append(" ");
                sb.Append(Name);
                sb.Append("(");

                int count = Parameters.Count;
                for (int i = 0; i < count; i++)
                {
                    TypeDescription parameter = Parameters[i];

                    sb.Append(parameter.Signature);
                    
                    if (i < count - 1) sb.Append(", ");                    
                }

                sb.Append(")");

                return sb.ToString();

            }
        }

        public bool Equals(MethodDescription other)
        {
            if (ReferenceEquals(null, other))
            {
                return false;
            }
            if (ReferenceEquals(this, other))
            {
                return true;
            }
            return Equals(other.Parameters, Parameters);
        }

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj))
            {
                return false;
            }
            if (ReferenceEquals(this, obj))
            {
                return true;
            }
            if (obj.GetType() != typeof (MethodDescription))
            {
                return false;
            }
            return Equals((MethodDescription) obj);
        }

        public override int GetHashCode()
        {
            return (Parameters != null ? Parameters.GetHashCode() : 0);
        }

        public static bool operator ==(MethodDescription left, MethodDescription right)
        {
            return Equals(left, right);
        }

        public static bool operator !=(MethodDescription left, MethodDescription right)
        {
            return !Equals(left, right);
        }
    }
}